package com.miyue.stepdemo

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Rect
import android.os.Looper
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import com.miyue.stepdemo.utils.DisplayUtil


/**
 * @author binjx
 * @date 2023/9/28 16:12
 * @purpose：
 */
class StepView : View {
    private var mPaint: Paint = Paint()
    private var text: String = ""
    private var textSize: Float = 10f
    private var type: Int = TYPE_START
    private var style: Int = STYLE_NOT_SELECTED
    // 开始画文字的X轴
    private var startPointText = 0f
    private var mWidthTotal = 0
    // 开始画文字的Y轴
    private var mHeight = 0f
    // 图标右侧凸出来的小箭头，越大越凸
    private val indentAndBulge = DisplayUtil.dpToPx(context, 5f).toFloat()

    companion object {
        const val TYPE_START = 0x00
        const val TYPE_MIDDLE = 0x01
        const val TYPE_STOP = 0x02

        const val STYLE_SELECTED = 10
        const val STYLE_NOT_SELECTED = 11
    }

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : this(
        context,
        attrs,
        defStyleAttr,
        0
    )

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int,
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
        //获取定义的一些属性
        val styleAttrs = context!!.obtainStyledAttributes(
            attrs,
            R.styleable.StepView,
            defStyleAttr,
            0
        )
        //数一数有多少个属性呢
        val indexCount = styleAttrs.indexCount
        // 循环遍历的方式，找到我们所定义的一些属性
        for (i in 0..indexCount) {
            //根据索引值给java代码中的成员变量赋值
            when (val index = styleAttrs.getIndex(i)) {
                R.styleable.StepView_text -> {
                    text = styleAttrs.getString(index).toString()
                }

                R.styleable.StepView_textSize -> {
                    textSize = styleAttrs.getDimension(index, 2f)
                    mPaint.textSize = textSize
                    getWidthAndHight()
                }

                R.styleable.StepView_type -> {
                    type = styleAttrs.getInt(index, type)
                }

                R.styleable.StepView_style -> {
                    style = styleAttrs.getInteger(index, STYLE_NOT_SELECTED)
                }
            }
        }
        //资源文件中的属性回收
        styleAttrs.recycle()
    }

    /**
     * 必须重写该方法，并使用 setMeasuredDimension 重新赋宽高值
     * 否则设置 wrap_content 不生效
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 获取宽高的测量模式
        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)
        // 获取宽高的测量大小
        val widthSpecSize = MeasureSpec.getSize(widthMeasureSpec)
        val heithtSpecSize = MeasureSpec.getSize(heightMeasureSpec)
        Log.e("gaodui", mWidthTotal.toString())
        if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            setMeasuredDimension(
                DisplayUtil.dpToPx(context, mWidthTotal),
                mHeight.toInt()
            )
        } else if (layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
            // 宽 / 高任意一个布局参数为= wrap_content时，都设置默认值
            setMeasuredDimension(DisplayUtil.dpToPx(context, mWidthTotal), heithtSpecSize)
        } else if (layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            // 宽 / 高任意一个布局参数为= wrap_content时，都设置默认值
            setMeasuredDimension(widthSpecSize, mHeight.toInt())
        }
    }

    /**
     * 该函数只会在 View 的大小发生改变时自动触发
     * 例如：初始化View、界面横竖屏的切换等。
     */
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        Log.e("onSizeChanged", "View的宽度：$w,高度$h")
    }

    /**
     * 如果自定义的 View 有子组件时，必须重写该方法，用以确定子组件在 View 中的位置.
     * 如果有需要自定义有子 View 的组件时，应该继承 ViewGroup 而不是 View，具体看情况自己分析
     */
    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        Log.e("onLayout","$left,$top,$right,$bottom")
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        mPaint.style = Paint.Style.FILL_AND_STROKE
        mPaint.strokeWidth = 0.5f
        // 消除锯齿
        mPaint.isAntiAlias = true
        mPaint.color = context.getColor(R.color.font_blue)
        val totalWidth = mWidthTotal + startPointText
        val path = Path()
        path.moveTo(0f, 0f)
        path.lineTo(totalWidth, 0f)
        val halfHeight = mHeight / 2f
        when (type) {
            TYPE_START -> {
                val rightBulge = totalWidth + indentAndBulge
                path.lineTo(rightBulge, halfHeight)
                path.lineTo(totalWidth, mHeight)
                path.lineTo(0f, mHeight)
            }

            TYPE_MIDDLE -> {
                val rightBulge = totalWidth + indentAndBulge
                path.lineTo(rightBulge, halfHeight)
                path.lineTo(totalWidth, mHeight)
                path.lineTo(0f, mHeight)
                path.lineTo(indentAndBulge, halfHeight)
            }

            else -> {
                path.lineTo(totalWidth, mHeight)
                path.lineTo(0f, mHeight)
                path.lineTo(indentAndBulge, halfHeight)
            }
        }
        path.lineTo(0f, 0f)
        path.close()
        canvas.drawPath(path, mPaint)
        mPaint.color =
            if (style == STYLE_NOT_SELECTED) context.getColor(R.color.font_black) else context.getColor(
                R.color.white
            )
        canvas.drawText(text, startPointText, mHeight / 1.5f, mPaint)
    }

    /**
     * 更新样式为选中
     */
    fun updateSelectedStyle() {
        style = STYLE_SELECTED
        if (Looper.myLooper() == Looper.getMainLooper()) {
            // 在UI线程更新UI
            invalidate()
        } else {
            // 在非UI线程更新UI
            postInvalidate()
        }
    }

    /**
     * 更新样式为未选中
     */
    fun updateNotSelectedStyle() {
        style = STYLE_NOT_SELECTED
        if (Looper.myLooper() == Looper.getMainLooper()) {
            // 在UI线程更新UI
            invalidate()
        } else {
            // 在非UI线程更新UI
            postInvalidate()
        }
    }

    fun setText(text: String) {
        this.text = text
        invalidate()
    }

    fun getText() = this.text

    fun getTextSize() = textSize

    fun setTextSize(textSize: Float) {
        this.textSize = textSize
        mPaint.textSize = textSize
        getWidthAndHight()
        invalidate()
    }

    private fun getWidthAndHight() {
        val textf = FloatArray(text.length)
        mPaint.getTextWidths(text, textf)
        var height = 0f
        var wightt = 0f
        textf.forEach {
            mWidthTotal += it.toInt()
            if (height < it) {
                height = it
            }
            if (wightt < it) {
                wightt = it
            }
        }
        // 字体的总宽度再加上两个字体的宽度
        mWidthTotal += wightt.toInt()
        mHeight = height * 2
        startPointText = wightt
    }

    fun getType() = type

    fun setType(type: Int) {
        this.type = type
        invalidate()
    }

    fun getStyle() = style

    fun setStyle(style: Int) {
        this.style = style
        invalidate()
    }
}